<?php
/**
 * Created by PhpStorm.
 * User: HP_USER
 * Date: 2018/5/14
 * Time: 15:41
 */

namespace app\order;

use app\Clearing\Clearing;
use app\common\Common;
use app\data\OrderData;
use app\data\ShopData;
use app\data\UserData;
use app\index\controller\User;
use app\pay\WeChatPay;
use think\Db;
use think\Exception;

class Order extends Base
{
    /**
     * 商品属性长度限制
     * @var array
     */
    private $goodAttr = [1, 50];

    private  $goods_value;
    /**
     * 买家留言长度限制
     * @var array
     */
    private $userMsg = [0, 150];

    /**
     * 发货方式长度限制
     * @var array
     */
    private $freightMethod = [2, 20];

    /**
     * 排序字段
     * @var array
     */
    private $sort = ['order_start_time', 'ship_time', 'receipt_time'];

    /**用户订单排序字段
     * @var
     */
    private $userOrderSort = ['order_start_time'];

    /**
     * 排序方法
     * @var array
     */
    private $sortType = ['desc', 'asc'];

    /**
     * @var array
     */
    private $freightNum = [1, 30];

    /**
     * 发货排序
     * @var array
     */
    private $orderSort = ['ship_time', 'receipt_time'];

    private $integral_rate;

    public function _initialize()
    {
        $this->integral_rate = config('integral_rate');
        parent::_initialize(); // TODO: Change the autogenerated stub

    }

    private function check($shop_id, $user_id, $goods_id, $address_id, $total_integral, $number, $goods_attr,
                           $user_msg,&$money)
    {

        if (Common::checkTableFieldsValue('drh_goods', 'shop_id', 'id', $goods_id, $shop_id) == $this->f_code) {
            return ['code' => $this->f_code, 'msg' => '购买错误的商品'];
        }
        if (Common::getTableValue('drh_user_info', 'user_integral', 'id', $user_id) < $total_integral) {
            return ['code' => $this->f_code, 'msg' => '积分用户不足!'];
        }
        if (Common::checkTableFields('drh_delivery_address', 'id', $address_id) == $this->f_code) {
            return ['code' => $this->f_code, 'msg' => '不存在此收货地址'];
        }
        if (!Common::checkNumber($number)) {
            return ['code' => $this->f_code, 'msg' => '商品数量必须为正整数'];
        }
        $res = Common::db_count("goods_stock,goods_attr_value,is_ware","","drh_goods","id=".$goods_id)[0]??array();
        if($res['is_ware'] == 0){
            $goods_attr_value = json_decode($res['goods_attr_value'],true)??unserialize($res['goods_attr_value']);
            $goods_stock = $res['goods_stock'];
            $money = Common::checkGoodsAttr($goods_attr_value,$goods_attr);
        }else{
            $goods_attr_value = unserialize($res['goods_attr_value']);
            $attr = explode('-',$goods_attr);
            $val = Common::attr_val($attr,$goods_attr_value);
            $goods_stock = $val['stock'];
            $money = $val['price'];
        }
        if ($number > $goods_stock) {
            return ['code' => $this->f_code, 'msg' => '超过最大库存'];
        }
        $check = [
            '买家留言' => ["{$this->userMsg[0]},{$this->userMsg[1]}}", $user_msg]
        ];
        $res = Common::checkLength($check);

        if ($res['code'] == $this->f_code) {
            return json($res);
        }

        return ['code' => $this->t_code];
    }


    private function checkShopVerify($shop_id)
    {
        $res = Common::getTableValue('drh_shop', 'verify_status', 'id', $shop_id);
        if ($res != 1) {
            return ['code' => $this->f_code, 'msg' => '商户正在审核,请稍后在试'];
        }
        return ['code' => $this->t_code];
    }

    /**
     * 创建订单
     * @param $shop_id
     * @param $user_id
     * @param $goods_id
     * @param $goods_attr
     * @param $total_integral
     * @param $number
     * @param array $user_get_coupon
     * @param $address_id
     * @param $user_msg
     * @param $open_id
     * @param $status |  优惠  1--砍价  2--优惠卷
     * @param $id
     * @return \think\response\Json
     */
    public function createOrder($shop_id, $user_id, $goods_id, $goods_attr, $total_integral, $number,
                                        $address_id, $user_msg, $open_id, $status = 0, $id = 0, array $user_get_coupon = [])
    {

        $res = $this->check($shop_id, $user_id, $goods_id, $address_id, $total_integral, $number, $goods_attr,
            $user_msg,$goods_money);
        if($goods_money < 0){
            return json(['code'=>$this->f_code,'msg'=>'不存在该商品属性']);
        }
        if ($res['code'] == $this->f_code) {
            return json($res);
        }
        $res = $this->checkShopVerify($shop_id);
        if ($res['code'] == $this->f_code) {
            return json($res);
        }
        $goods = Common::getTableValue('drh_goods', ['goods_price', 'goods_freight'], 'id', $goods_id);//获取商品价格、运费
        $goods_price = $goods_money+$goods['goods_price'];//商品价格
        $goods_freight = $goods['goods_freight'];//商品运费

        $total_money = $money = $goods_price * $number;//商品总价格

        $data = $this->discount($total_money, $money, $user_get_coupon, $status, $id);

        if ($data['code'] != $this->t_code) {
            return json($data);
        }
        $money = $data['money'];//优惠后商品总价格
        $coupon_info = $data['coupon_info'];//优惠详情
        if (($money + $goods_freight) < $total_integral * $this->integral_rate) {
            return json(['code' => $this->f_code, 'msg' => '输入积分错误']);
        }
        $freight_price = $freight = $goods_freight;
        if ($total_integral * $this->integral_rate > $money) {//有抵扣运费
            $freight_price = $freight - ($total_integral * $this->integral_rate - $money);
            if ($freight_price < 0) {//输入了多的积分
                return json(['code' => $this->f_code, 'msg' => '积分输入超额']);
            }//全部积分支付   运费积分支付
            $money = 0;
        } else {//没有抵扣运费
            $money = $money - $total_integral * $this->integral_rate;
        }
        $order = new OrderData();
        $user = new User();
        $address = $user->showAddressInfo($user_id, $address_id);
        $address = json_decode($address, true);
        $address = $address['data'];
        $res = $order->addOrder($shop_id, $user_id, $goods_id, $goods_price, $money, $goods_attr,
            $total_integral, $number,
            json_encode($coupon_info), json_encode($address), $user_msg, $freight, $freight_price);
        $order_num = $res['order_num'];
        if ($money == 0 && $freight_price == 0) {
            return json(['code' => $this->t_code, 'msg' => '支付成功', 'data' => []]);
        }
        $pay = new WeChatPay();
        $res = $pay->WxPay($open_id, $order_num, 'CommissionRecharge', $money + $freight_price);
        $pay->inventory($goods_id,$number,$goods_attr);
        return json(['code' => $this->t_code, 'msg' => 'OK', 'data' => $res]);
    }

    /**
     * 待支付
     * @param $order_num
     * @param $open_id
     * @return \think\response\Json
     */
    public function waitPay($order_num, $open_id)
    {
        $goods = Common::getTableValue('drh_goods_order', ['price', 'freight_price', 'user_id'], 'order_num', $order_num);//获取应该支付的价格
        if (empty($goods)) {
            return json(['code' => $this->f_code, 'msg' => '不存在该订单']);
        }
        $user_id = Common::getTableValue('drh_user_info', 'id', 'user_open_id', $open_id);
        if (empty($user_id)) {
            return json(['code' => $this->f_code, 'msg' => 'openid错误']);
        }
        if ($user_id != $goods['user_id']) {
            return json(['code' => $this->f_code, 'msg' => '不是同一个人']);
        }
        $pay = new WeChatPay();
        $res = $pay->WxPay($open_id, $order_num, 'CommissionRecharge', $goods['price'] + $goods['freight_price']);
        return json(['code' => $this->t_code, 'msg' => 'OK', 'data' => $res]);
    }

    /**
     * 折扣 优惠
     * @param $total_money
     * @param $money
     * @param $user_get_coupon
     * @param $status
     * @param $id
     * @return array|bool
     * @throws Exception
     */
    private function discount($total_money, $money, $user_get_coupon, $status, $id)
    {

        switch ($status) {
            case 1 :
                $res = $this->bargain($total_money, $id);
                break;
            case 2:
                $res = $this->coupon($total_money, $money, $user_get_coupon);
                break;
            default :
                $res = ['code' => $this->t_code, 'money' => $money, 'coupon_info' => []];
                break;
        }
        return $res;
    }

    private function coupon($total_money, $money, $user_get_coupon)
    {
        $coupon_info = [];
        $coupon = new Coupon();
        if (!empty($user_get_coupon)) {
            foreach ($user_get_coupon as $k => $v) {
                $res = $coupon->discountMoney($total_money, $k, $v, $money);
                if ($res['code'] = $this->f_code) {
                    return $res;
                }
                $coupon_info[] = $res;
                $money = $res['money'];
            }
        }
        return ['money' => $money, 'coupon_info' => $coupon_info, 'code' => $this->t_code];
    }

    /**
     * 砍价
     * @param $total_money
     * @param $id
     * @return array
     */
    private function bargain($total_money, $id)
    {
        $shopData = new ShopData();
        $res = $shopData->getBargainGoodInfo($id);
        $bargain_num = $res['bargain_num'];
        $bargain_total_num = $res['bargain_total_num'];
        $num = $bargain_total_num;
        $bargain_money = $num * $res['bargain_once_money'];//砍了多少钱
        if ($bargain_num == 0) {
            $money = $total_money - $res['bargain_total_money'];
            if ($money < 0) {
                return ['code' => $this->f_code, 'msg' => '砍价金额错误'];
            } else {
                $data = [
                    'code' => $this->t_code,
                    'money' => $money,
                    'coupon_info' => [
                        'bargain',
                        "{$id}--{$num}--{$res['bargain_once_money']}--{$res['bargain_total_money']}"
                    ]
                ];
            }
        } else {
            $money = $total_money - $bargain_money;
            $data = [
                'code' => $this->t_code,
                'money' => $money,
                'coupon_info' => [
                    'bargain',
                    "{$id}--{$num}--{$bargain_money}--{$res['bargain_total_money']}"
                ]
            ];
        }
        return $data;
    }

    /**
     * 展示
     * @param $shop_id
     * @param int $goods_status
     * @param int $page
     * @param int $pre
     * @param array $sort
     * @return \think\response\Json
     */
    public function show($shop_id, $goods_status = 2, $page = 1, $pre = 15, array $sort = ['order_start_time' => 'desc'])
    {
        //校验页码数和页码条数已经排序
        $res = Common::checkShow($page, $pre, $this->sort, $this->sortType, $sort);
        if ($res['code'] == $this->f_code) {
            return json($res);
        }
        if (Common::checkTableFields('drh_shop', 'id', $shop_id) == $this->f_code) {
            return json(['code' => $this->f_code, 'msg' => '不存在该商户']);
        }
        if ($goods_status != 0 && $goods_status != 1 && $goods_status != 2 && $goods_status != 3 && $goods_status != 4) {
            return json(['code' => $this->f_code, 'msg' => '非法操作']);
        }
        $where ="a.shop_id ={$shop_id} and a.pay_status > 1";
        if($goods_status !=4){
            $where.= " and a.goods_status ={$goods_status}";
        }

        $order = new OrderData();
        $list = $order->show($where, $page, $pre, $sort);
        foreach ($list as $k => $v) {
            $address = json_decode($v['address'], true);
            unset($address['id']);
            unset($address['user_id']);
            $list[$k]['address'] = $address;
        }
        return json([
            'code' => $this->t_code,
            'msg' => 'OK',
            'data' => [
                'list' => $list,
                'total' => $order->total($where,'drh_goods_order a'),
            ]
        ]);
    }

    private function checkShip($freight_method, $freight_num)
    {
        $check = [
            '发货方式' => ["{$this->freightMethod[0]},{$this->freightMethod[1]}}", $freight_method],
        ];
        $res = Common::checkLength($check);
        if ($res['code'] == $this->f_code) {
            return $res;
        }
        $check = ['发货单号' => ["{$this->freightNum[0]},{$this->freightNum[1]}}", $freight_num],];
        $res = Common::checkLength($check);
        if ($res['code'] == $this->f_code) {
            return $res;
        }
        if (!Common::checkNumber($freight_num)) {
            return ['code' => $this->f_code, 'msg' => '订单号错误'];
        }
        return ['code' => $this->t_code];
    }

    /**
     * 发货
     * @param $order_num
     * @param $freight_method
     * @param $freight_num
     * @return array|\think\response\Json
     */
    public function ship($order_num, $freight_method, $freight_num)
    {
        $res = Common::getTableValue('drh_goods_order', 'goods_status', 'order_num', $order_num);
        if (empty($res) && $res != 0) {
            return json(['code' => $this->f_code, 'msg' => '不存在该订单']);
        }
        if ($res != 0) {
            return json(['code' => $this->f_code, 'msg' => '请勿重复发货']);
        }
        $check = $this->checkShip($freight_method, $freight_num);
        if ($check['code'] == $this->f_code) {
            return json($check);
        }
        $order = new OrderData();
        return json($order->ship($order_num, $freight_method, $freight_num));
    }

    /**
     * 修改发货方式
     * @param $order_num
     * @param $freight_method
     * @param $freight_num
     * @return \think\response\Json
     */
    public function editFreightNum($order_num, $freight_method, $freight_num)
    {
        $res = Common::getTableValue('drh_goods_order', 'goods_status', 'order_num', $order_num);
        if (empty($res) && $res != 0) {
            return json(['code' => $this->f_code, 'msg' => '不存在该订单']);
        }
        $check = $this->checkShip($freight_method, $freight_num);
        if ($check['code'] == $this->f_code) {
            return json($check);
        }
        $order = new OrderData();
        return json($order->editFreightNum($order_num, $freight_method, $freight_num));
    }

    /**
     * 订单结束
     * @param $order_num
     * @param $pay_status
     * @return array
     */
    public function endOrder($order_num, $pay_status)
    {

        $file = "./temp.txt";
        $fp = fopen($file, 'r');
        Db::startTrans();
        try {
            if (Common::checkTableFields('drh_goods_order', 'order_num', $order_num) == $this->f_code) {
                return ['code' => $this->f_code, 'msg' => '不存在该订单'];
            }

            $time = time();
            $order = new OrderData();
            $order_info = $order->getOrderInfo($order_num);

            $order_info ['order_num'] = $order_num;
            $money = $order_info['price'];
//            $clear = new Clearing('goods_order');
//            $clear->clearing([
//                'order_num' => $order_num,
//                'time' => $time,
//                'pay_status' => $pay_status,
//                'money' => $money,
//                'order_info' => $order_info
//            ]);
            $order->endOrder($order_num, 2, $time);//订单结算
            Db::commit();
            $this->delGoodsBargain($order_info);
            fclose($fp);
            return json(['code' => $this->t_code, 'msg' => 'OK']);
        } catch (\Exception $e) {
            Db::rollback();
            fclose($fp);
            return json(['code' => $this->f_code, 'msg' => $e->getMessage()]);
        }
    }

    private function delGoodsBargain($order_info)
    {
        $goods_attr=$order_info['goods_attr_value'];
        $user=new UserData();
        $user->delGoodsBargain($goods_attr,$order_info['goods_id'],$order_info['shop_id'],$order_info['user_id']);
    }

    /**
     * 显示用订单信息
     * @param $user_id
     * @param int $page
     * @param int $pre
     * @param $status
     * @param array $sort
     * @return \think\response\Json
     */
    public function showUserOrder($user_id, $status, $page = 1, $pre = 5, array $sort = ['order_start_time' => 'desc'])
    {
        //校验页码数和页码条数已经排序
        $res = Common::checkShow($page, $pre, $this->userOrderSort, $this->sortType, $sort);
        if ($res['code'] == $this->f_code) {
            return json($res);
        }
        $order = new OrderData();
        $data = $order->showUserOrder($this->getWhere($status, $user_id), $page, $pre, $sort);
        foreach ($data as $k => $v) {
            $data[$k]['goods_img'] = json_decode($v['goods_img'])??unserialize($v['goods_img']);
        }
        return json([
            'code' => $this->t_code,
            'msg' => 'OK',
            'data' => $data
        ]);
    }

    private function getWhere($status, $open_id)
    {
        $where = "b.id='{$open_id}' and a.del_status=1";
        switch ($status) {
            case 1://待付款
                $where .= " and a.pay_status=0";
                break;
            case 2://待发货
                $where .= " and a.pay_status >1 and a.goods_status=0";
                break;
            case 3://待收货
                $where .= " and a.pay_status >1 and a.goods_status=1";
                break;
            case 4://待评论
                $where .= " and a.pay_status >1 and a.goods_status=2 and e.comment_integral is null";
                break;
            case 5://退货
                $where .= " and a.goods_status = 3";
                break;
            default:
                break;
        }
        return $where;
    }

    /**
     * 显示订单详情
     * @param $id
     * @param $user_id
     * @param $order_num
     * @return \think\response\Json
     */
    public function showUserOrderInfo($id, $user_id, $order_num)
    {
        $order = new OrderData();
        $data = $order->showUserOrderInfo($id, $user_id, $order_num);
        $shop_id=$data['shop_id'];
        $shopData=new ShopData();
        $data['shop_tel']=$shopData->getShopTel($shop_id);
        $user_get_coupon = json_decode($data['user_get_coupon'], true);
        if (empty($user_get_coupon)) {
            $data['user_get_coupon'] = [];
        } else {
            $data['user_get_coupon'] = json_decode($this->getCouponInfo($user_get_coupon),true);
        }
        if (!empty($data)) {
            $data['goods_img'] = json_decode($data['goods_img']);
            $data['address'] = json_decode($data['address']);
        }
        return json([
            'code' => $this->t_code,
            'msg' => 'OK',
            'data' => $data
        ]);
    }

    public function checkTransactionOrder($goods_id)
    {
        if (Common::checkTableFields('drh_goods', 'id', $goods_id) == $this->f_code) {
            return json(['code' => $this->f_code, 'msg' => '不存在该商品']);
        }
        $order = new OrderData();
        $count = $order->total(" order_start_time>0 and goods_status !=2 and goods_id={$goods_id}");
        return $count;
    }

////////////////////////////////////////////////////----后端----\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

    /**
     * 显示订单号
     * @param $goods_status
     * @param int $page
     * @param int $pre
     * @param array $sort
     * @return \think\response\Json
     */
    public function showOrderNum($goods_status, $page = 1, $pre = 15, array $sort = ['receipt_time' => 'desc'])
    {

        //校验页码数和页码条数已经排序
        $res = Common::checkShow($page, $pre, $this->orderSort, $this->sortType, $sort);
        if ($res['code'] == $this->f_code) {
            return json($res);
        }

        if ($goods_status != 1 && $goods_status != 3) {
            return json(['code' => $this->f_code, 'msg' => '非法操作']);
        }
        $where = $goods_status == 1 ? " goods_status in (1,2) " : " goods_status=3 ";
        $order = new OrderData();
        $data = $order->showOrderNum($where, $page, $pre, $sort);
        return json([
            'code' => $this->t_code,
            'msg' => 'OK',
            'data' => [
                'list' => $data,
                'total' => $order->total($where),
            ]
        ]);
    }

    /**
     * 获取总订单数
     * @return \think\response\Json
     */
    public function getOrderNumber()
    {
        $time_end = time();
        $time_start = strtotime(date('Y-m-d', $time_end));

        return json([
            'code' => $this->t_code,
            'msg' => 'OK',
            'data' => (new OrderData())->total("order_end_time >={$time_start} and order_end_time <= {$time_end}")
        ]);
    }

    /**
     * 显示订单详情
     * @param $order_num
     * @return \think\response\Json
     */
    public function showOrderInfo($order_num)
    {
        $data = (new OrderData())->showOrderInfo($order_num);
        $address = json_decode($data['address'], true);
        $user_get_coupon = json_decode($data['user_get_coupon'], true);
        if (empty($user_get_coupon)) {
            $data['user_get_coupon'] = [];
        } else {
            $data['user_get_coupon'] = json_decode($this->getCouponInfo($user_get_coupon),true);
        }
        unset($address['id']);
        unset($address['user_id']);
        $data['address'] = $address;
        return json([
            'code' => $this->t_code,
            'msg' => 'OK',
            'data' => $data
        ]);
    }

    private function getCouponInfo($info)
    {
        if ($info[0] == 'bargain') {
            $arr = explode('--', $info[1]);
            $res = [
                'title' => '好友砍价',
                'num' => $arr[1],
                'bargain_once_money' => $arr[2],
                'bargain_total_money' => $arr[3],
            ];
        } else {
            $res = [];
        }
        return json_encode($res);
    }

    /**
     * 热卖商品
     * @param $pre
     * @return \think\response\Json
     */
    public function showHotGoods($pre)
    {
        if (!Common::checkNumber($pre)) {
            return json(['code' => $this->f_code, 'msg' => '非法操作']);
        }
        $order = new OrderData();
        $data = $order->showHotGoods($pre);
        if (!empty($data)) {
            $data = $this->getImg($data);
        }
        return json([
            'code' => $this->t_code,
            'msg' => 'OK',
            'data' => $data
        ]);
    }

    /**
     * 代理商品最多的
     * @param $pre
     * @return \think\response\Json
     */
    public function showProxyGoods($pre)
    {
        if (!Common::checkNumber($pre)) {
            return json(['code' => $this->f_code, 'msg' => '非法操作']);
        }
        $order = new OrderData();
        $data = $order->showProxyGoods($pre);
        if (!empty($data)) {
            $data = $this->getImg($data);
        }
        return json([
            'code' => $this->t_code,
            'msg' => 'OK',
            'data' => $data
        ]);
    }

    /**
     * 显示好评商品
     * @param $pre
     * @return \think\response\Json
     */
    public function showRatingsGoods($pre)
    {
        if (!Common::checkNumber($pre)) {
            return json(['code' => $this->f_code, 'msg' => '非法操作']);
        }
        $order = new OrderData();
        $data = $order->showRatingsGoods($pre);
        if (!empty($data)) {
            $data = $this->getImg($data);
        }
        return json([
            'code' => $this->t_code,
            'msg' => 'OK',
            'data' => $data
        ]);
    }

    /**
     * 退货
     * @param $pre
     * @return \think\response\Json
     */
    public function showReturnsGoods($pre)
    {
        if (!Common::checkNumber($pre)) {
            return json(['code' => $this->f_code, 'msg' => '非法操作']);
        }
        $order = new OrderData();
        $data = $order->showReturnsGoods($pre);
        if (!empty($data)) {
            $data = $this->getImg($data);
        }
        return json([
            'code' => $this->t_code,
            'msg' => 'OK',
            'data' => $data
        ]);
    }

    /**
     * 获取图片
     * @param $data
     * @return mixed
     */
    private function getImg($data)
    {
        foreach ($data as $k => $v) {
            $img = json_decode($v['goods_img']);
            if (empty($img)) {
                $data[$k]['goods_img'] = '';
            } else {
                $data[$k]['goods_img'] = $img[0];
            }
        }
        return $data;
    }

    public function getOrderNum($start_time, $end_time)
    {
        $order = new OrderData();
        return $order->getOrderNum($start_time, $end_time);
    }

    public function test()
    {
        $info['out_trade_no'] = 'o11113';
        $status = 1;
        $order = new Order();
        $res = $order->endOrder($info['out_trade_no'], $status);
        dump($res);
    }

    public function confirmReceipt($order_num,$user_id,$goods_status=2)
    {

        $res = Common::getTableValue('drh_goods_order', 'pay_status', ['order_num','user_id'], [$order_num,$user_id]);
        if (empty($res) || $res <=1) {
            return json(['code' => $this->f_code, 'msg' => '不存在该订单']);
        }
        if(!in_array($goods_status,[2,3])){
            return json(['code' => $this->f_code, 'msg' => '传递参数错误']);
        }
        $order = Db::name('drh_goods_order')->where('order_num',$order_num)->find();
        $clear = new Clearing('goods_order');
        $orderData = new OrderData();
        $order_info = $orderData->getOrderInfo($order_num);
            $clear->clearing([
                'order_num' => $order_num,
                'time' => $order['ship_time'],
                'pay_status' => $order['pay_status'],
                'money' => $order['price'],
                'order_info' => $order_info
            ]);
        $order = new OrderData();
        $res=$order->confirmReceipt($order_num,$user_id,$goods_status);
        if($res){
            return json(['code' => $this->t_code, 'msg' => '操作成功']);
        }else{
            return json(['code' => $this->f_code, 'msg' => '系统繁忙请稍后在试']);
        }
    }
}